
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <regex>

#include "Home.h"
#include "Util.h"
#include "ProDataIO.h"
#include "Parse.h"

using namespace std;

/**
 * It returns a vector of strings containing the names of all files in the directory given by dirname
 * 
 * @param file the file name to be searched, including the path.
 * 
 * @return A vector of strings.
 */
vector<string> GetFiles(const string &file) 
{
    DIR     *dir;
    char    basePath[256], *getcwdReturn;

    struct dirent   *ptr;
    string          f(file), fdir, fname, dname, bpath, curDir("./");
    vector<string>  strs;
    
    memset(basePath, '\0', sizeof(basePath));
    getcwdReturn = getcwd(basePath, sizeof(basePath));

    std::size_t iPos = f.find_last_of("/\\");
    if(iPos == string::npos){
        fdir = curDir;
        fname = f;
    }else{
        fdir = curDir + f.substr(0,iPos);
        fname = f.substr(iPos+1);
    }
    std::regex regex(fname);
    
    if((dir = opendir(fdir.c_str())) == NULL){
        Fatal("Can not open dir %s, file=%s", fdir.c_str(), file.c_str());
    }

    while((ptr = readdir(dir)) != NULL){
        if(strcmp(ptr->d_name, ".") == 0 || 
           strcmp(ptr->d_name, "..") == 0){     //current dir OR paraent dir
          continue;
        }else if(ptr->d_type == 8){   //file
            dname = ptr->d_name;
            if(std::regex_match(dname, regex)){
                strs.push_back(fdir + "/" + dname);
            }
        }else if(ptr->d_type == 10){    // link file

        }else if(ptr->d_type == 4){     //  dir

        }
    }

    closedir(dir);
    return(strs);
}


/**
 * > Given a file name, return the directory name
 * 
 * @param file The file name to be parsed.
 * 
 * @return The directory name of the file.
 */
std::string DirName(const std::string &file)
{
    std::string f(file);
    std::size_t iPos = f.find_last_of("/\\");
    if(iPos ==  std::string::npos){
        return std::string("./");
    }else{
        return std::string("./") + f.substr(0,iPos);
    }
}

/**
 * Given a file name, return the file name without the path
 * 
 * @param file The file name to be parsed.
 * 
 * @return The base name of the file.
 */
std::string BaseName(const std::string &file)
{
    std::string f(file);
    std::size_t iPos = f.find_last_of("/\\");
    if(iPos ==  std::string::npos){
        return file;
    }else{
        return f.substr(iPos+1);
    }

}

/**
 * > Given a file name, return the directory name and the base name
 * 
 * @param file the full path of the file
 * @param dirName the directory name of the file
 * @param baseName the name of the file without the directory
 * 
 * @return the directory name and the base name of the file.
 */
void DirAndBaseName(const std::string &file, std::string &dirName, std::string &baseName)
{
    std::string f(file),curDir("./");
    std::size_t iPos = f.find_last_of("/\\");

    if(iPos == string::npos){
        dirName = curDir;
        baseName = f;
    }else{
        dirName = curDir + f.substr(0,iPos);
        baseName = f.substr(iPos+1);
    }
    return;
}



